#include <stdio.h>
#include "pkt_list.h"

PKTELEM* PKTELEM_malloc(int pid, uint8_t *pkt_buf) {
	PKTELEM *pkt_elem;

	if(!pkt_buf) return NULL;

	pkt_elem = (PKTELEM*)os_calloc(sizeof(PKTELEM));
	if(!pkt_elem) return NULL;

	pkt_elem->pid = pid;
	memcpy(pkt_elem->pkt_buf, pkt_buf, PKT_LEN);

	return pkt_elem;
}

void PKTELEM_free(PKTELEM *elem) {
	if(!elem) return;
	os_free(elem);
}


LIST_XXXX(PKTELEM, node);


int PKTELEM_sec_2_pkt(uint8_t *pkt_all_buf, int pkt_len, int pkt_cnt_max, int pid, uint8_t *sec_buf) {
	uint8_t head_buf[] = {0x47, 0x40, 0x00, 0x10};

	uint8_t *pkt_buf;
	int sec_all_len, sec_pos = 0;
	int pkt_cnt = 0, pkt_pos = 0, copy_len;

	if((!pkt_all_buf) || (!sec_buf) || (pkt_len < PKT_LEN)) return 0;

	// 清空
	memset(pkt_all_buf, 0xFF, pkt_len * pkt_cnt_max);

	// 放PID	
	pid &= 0x1FFF;
	head_buf[1] |= (pid >> 8);
	head_buf[2]  = (pid >> 0);

	sec_all_len = os_get_all_sec_len(sec_buf);
	for(sec_pos = 0, pkt_cnt = 0, copy_len = 0; sec_pos < sec_all_len; sec_pos += copy_len, pkt_cnt++) {
		if(pkt_cnt >= pkt_cnt_max) break;

		pkt_pos = 0;
		pkt_buf = pkt_all_buf + pkt_len * pkt_cnt;

		// 4B_包头
		memcpy(pkt_buf + pkt_pos, head_buf, sizeof(head_buf));
		pkt_pos += sizeof(head_buf);

		// 清除start_flag
		head_buf[1] &= 0xBF;

		// point_field
		if(sec_pos == 0) pkt_buf[pkt_pos++] = 0;

		// 载荷
		copy_len = os_min(sec_all_len - sec_pos, PKT_LEN - pkt_pos);
		memcpy(pkt_buf + pkt_pos, sec_buf + sec_pos, copy_len);
		pkt_pos += copy_len;
	}

	return pkt_cnt;
}

void PKTELEM_LIST_insert_sec(LIST *pkt_list, uint8_t *sec_buf, int pid) {
	PKTELEM *pkt_elem;
	uint8_t pkt_all_buf[PKT_LEN * 8];
	int pkt_idx, pkt_cnt;

	if((!pkt_list) || (!sec_buf)) return;

	pkt_cnt = PKTELEM_sec_2_pkt(pkt_all_buf, PKT_LEN, sizeof(pkt_all_buf) / PKT_LEN, pid, sec_buf);
	
	for(pkt_idx = 0; pkt_idx < pkt_cnt; pkt_idx++) {
		PKTELEM_LIST_add(pkt_list, (pkt_elem = PKTELEM_malloc(pid, pkt_all_buf + PKT_LEN * pkt_idx)));
		if (!pkt_elem) continue;
	}
}


int PKTELEM_LIST_write_file(LIST *pkt_list, FILE *pfile, uint8_t cc_buf[0x1FFF + 1]) {
	PKTELEM *pkt_elem;
	int pos = 0;
	uint8_t cc;

	if(!pkt_list || !pfile || !cc_buf) return 0;

	list_for_each_entry(pkt_elem, &pkt_list->node, node, PKTELEM) {
		cc = cc_buf[pkt_elem->pid & 0x1FFF]++;

		pkt_elem->pkt_buf[3] &= 0xF0;
		pkt_elem->pkt_buf[3] |= (cc & 0x0F);

		fwrite(pkt_elem->pkt_buf, 1, PKT_LEN, pfile);
		pos += PKT_LEN;
	}

	return pos;
}
